home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / system / ms_sh22b.zip / src / system.c < prev   
C/C++ Source or Header  |  1993-12-01  |  49KB  |  2,345 lines

  1. /* MS-DOS System Function with Swaping - system (3C)
  2.  *
  3.  * MS-DOS System - Copyright (c) 1990,1,2 Data Logic Limited.
  4.  *
  5.  * This code is subject to the following copyright restrictions:
  6.  *
  7.  * 1.  Redistribution and use in source and binary forms are permitted
  8.  *     provided that the above copyright notice is duplicated in the
  9.  *     source form.
  10.  *
  11.  * Author:
  12.  *    Ian Stewartson
  13.  *    Data Logic, Queens House, Greenhill Way
  14.  *    Harrow, Middlesex  HA1 1YR, UK.
  15.  *    istewart@datlog.co.uk or ukc!datlog!istewart
  16.  *
  17.  *    $Header: /usr/users/istewart/src/shell/sh2.2/RCS/system.c,v 2.4 1993/08/25 16:04:22 istewart Exp $
  18.  *
  19.  *    $Log: system.c,v $
  20.  *    Revision 2.4  1993/08/25  16:04:22  istewart
  21.  *    Add support for new options
  22.  *
  23.  *    Revision 2.3  1993/06/14  10:59:58  istewart
  24.  *    More changes for 223 beta
  25.  *
  26.  *    Revision 2.2  1993/06/02  09:52:35  istewart
  27.  *    Beta 223 Updates - see Notes file
  28.  *
  29.  *    Revision 2.1  1993/01/26  18:35:36  istewart
  30.  *    Fix OS2 version bug (missing semi-colon).
  31.  *
  32.  *    Revision 2.0  1992/05/21  16:49:54  Ian_Stewartson
  33.  *    MS-Shell 2.0 Baseline release
  34.  *
  35.  *
  36.  * MODULE DEFINITION:
  37.  *
  38.  * This is a version of the standard system(3c) library function.  The only
  39.  * difference is that it supports swapping and MS-SHELL EXTENDED_LINE
  40.  * processing.
  41.  *
  42.  * To get the OS2 version, compile with -DOS2
  43.  *
  44.  * There are four macros which can be changed:
  45.  *
  46.  * GET_ENVIRON        To get a variable value from the environment
  47.  * FAIL_ENVIRON        The result on failure
  48.  * FATAL_ERROR        Handle a fatal error message
  49.  * SHELL_SWITCH        The command switch to the SHELL.
  50.  *
  51.  * This module replaces the standard Microsoft SYSTEM (3C) call.  It should
  52.  * work with most models.  It has been tested in Large and Small model.
  53.  * When you link a program using the swapper, the swapper front end
  54.  * (swap.obj) must be the first object model on the linker command line so
  55.  * that it is located immediately after the PSP.  For example:
  56.  *
  57.  *    link swap+x1+x2+x3+system,x1;
  58.  * or
  59.  *    cl -o z1 swap.obj x1.obj x2.obj x3.obj system
  60.  *
  61.  * The location of the system object is not relevent.
  62.  */
  63.  
  64. #include <sys/types.h>
  65. #include <sys/stat.h>
  66. #include <stdio.h>
  67. #include <stdlib.h>
  68. #include <errno.h>
  69. #include <limits.h>
  70. #include <ctype.h>
  71. #include <fcntl.h>
  72. #include <unistd.h>
  73. #include <string.h>
  74. #include <signal.h>
  75. #include <dirent.h>
  76.  
  77. #if defined (__TURBOC__)
  78. #  include <dir.h>
  79. #endif
  80.  
  81. #ifdef DL_MAKE
  82. #  include "make.h"
  83. #endif
  84.  
  85. #if defined(OS2) || defined (__OS2__)
  86. #  define INCL_DOSSESMGR
  87. #  define INCL_DOSMEMMGR
  88. #  define INCL_DOSPROCESS
  89. #  define INCL_WINSWITCHLIST
  90. #  define INCL_DOSERRORS
  91. #  include <os2.h>
  92. #else
  93. #  include <dos.h>
  94. #endif
  95.  
  96. #ifdef __OS2__
  97. #  define F_LOCAL
  98. #else
  99. #  define F_LOCAL        near
  100. #endif
  101.  
  102. #ifndef P_WAIT
  103. #  define P_WAIT    0
  104. #endif
  105.  
  106. /*
  107.  * Externals declared by the swapper
  108.  */
  109.  
  110. #if !defined(OS2) && !defined (__OS2__)
  111. extern char far        cmd_line[];    /* Command line            */
  112. extern char far        path_line[];    /* Process path            */
  113. extern unsigned int far    SW_intr;    /* interrupt pending        */
  114. extern unsigned int far    SW_Blocks;    /* Number of blocks to read    */
  115. extern int far        SW_fp;        /* File or EMS Handler        */
  116. extern unsigned int far    SW_EMsize;    /* Number of extend memory blks    */
  117. extern unsigned long far SW_EMstart;    /* Start addr of extend mem    */
  118.  
  119. #define SWAP_TO_DISK    1        /* Swap to disk            */
  120. #define SWAP_TO_Ext    2        /* Swap to extended memory    */
  121.                     /* Not recommended - no mgt    */
  122. #define SWAP_TO_EMS    3        /* Swap to EMS            */
  123. #define SWAP_TO_XMS    4        /* Swap to XMS            */
  124.  
  125. extern unsigned int far    SW_Mode;    /* Type of swapping to do    */
  126. extern unsigned int far    SW_EMSFrame;    /* EMS Frame segment        */
  127. extern bool far        SW_I23_InShell;    /* In the shell            */
  128.  
  129. /* Functions */
  130.  
  131. static void F_LOCAL    ClearSwapFile (void);
  132. extern int far        SA_spawn (char **);
  133. extern void (interrupt far *SW_I23_V) (void);    /* Int 23 address    */
  134. extern void (far    *SW_XMS_Driver) (void);    /* XMS Driver Interface    */
  135. extern int far        SW_XMS_Gversion (void);
  136. extern int far        SW_XMS_Allocate (unsigned int);
  137. extern int far        SW_XMS_Free (int);
  138. extern unsigned int far    SW_XMS_Available (void);
  139. extern void interrupt far SW_Int23 (void);    /* Int 23 New address    */
  140. extern void interrupt far SW_Int00 (void);    /* Int 00 New address    */
  141. #endif
  142.  
  143. #define FFNAME_MAX    (PATH_MAX + NAME_MAX + 3)
  144.  
  145. /*
  146.  * Convert to bool
  147.  */
  148.  
  149. #define C2bool(c)    (bool)((c) ? TRUE : FALSE)
  150.  
  151. /* Set these to the appropriate values to get environment variables.  For
  152.  * make the following values work.  Normally, getenv and (char *)NULL should
  153.  * be used.
  154.  */
  155.  
  156. #ifdef DL_MAKE
  157. #define GET_ENVIRON(p)        GetMacroValue (p)
  158. #define FAIL_ENVIRON        Nullstr
  159. #define FATAL_ERROR(a)        PrintFatalError (a)
  160. #define SHELL_SWITCH        "-ec"
  161. #define WINDOW_NAME        "DL Make"
  162. #else
  163. #define FATAL_ERROR(a)        { fputs (a, stderr); fputc ('\n', stderr); exit (1); }
  164. #define GET_ENVIRON(p)        getenv (p)
  165. #define FAIL_ENVIRON        (char *)NULL
  166. #define SHELL_SWITCH        "-c"
  167. #ifdef TEST
  168. #define WINDOW_NAME        "TEST"
  169. #else
  170. #define WINDOW_NAME
  171. #endif
  172. #endif
  173.  
  174. /* Declarations */
  175.  
  176.                 /* Open in create mode for swap file    */
  177. #define O_SMASK        (O_RDWR | O_CREAT | O_TRUNC | O_BINARY)
  178.  
  179. /*
  180.  * Result from FindLocationOfExecutable
  181.  */
  182.  
  183. #define EXTENSION_NOT_FOUND    0    /* Cannot find file        */
  184. #define EXTENSION_EXECUTABLE    1    /* OS/2 or DOS .exe or .com    */
  185.  
  186. /*
  187.  * Some MSDOS Swapper info
  188.  */
  189.  
  190. #if !defined(OS2) && !defined (__OS2__)
  191. #define CMD_LINE_MAX    127    /* Max command line length        */
  192.  
  193. /* MSDOS Memory Control Block chain structure */
  194.  
  195. #pragma pack (1)
  196. struct MCB_list    {
  197.     char        MCB_type;    /* M or Z            */
  198.     unsigned int    MCB_pid;    /* Process ID            */
  199.     unsigned int    MCB_len;    /* MCB length            */
  200. };
  201. #pragma pack ()
  202.  
  203. #define MCB_CON        'M'        /* More MCB's            */
  204. #define MCB_END        'Z'        /* Last MCB's            */
  205.  
  206. /* Swap Mode */
  207.  
  208. #define SWAP_OFF    0x0000        /* No swapping            */
  209. #define SWAP_DISK    0x0001        /* Disk only            */
  210. #define SWAP_EXTEND    0x0002        /* Extended memory        */
  211. #define SWAP_EXPAND    0x0004        /* Expanded memory        */
  212.  
  213. static int    Swap_Mode = (SWAP_DISK | SWAP_EXPAND | SWAP_EXTEND);
  214. static char    *NoSwapFiles = "No Swap files";
  215. static char    *MS_emsg = "WARNING - %s Error (%x)";
  216. static char    *MS_Space = "WARNING - %s out of space";
  217. static char    *SwapFailed = "%s swap failed (%x)";
  218. static char    *Swap_File = (char *)NULL;    /* Swap file    */
  219. #endif
  220.  
  221. static char    *Extend_file = (char *)NULL;
  222.  
  223. #if defined (OS2) || defined (__OS2__)
  224.  
  225. #define CMD_LINE_MAX        16000
  226. #define EXTENSION_COUNT        2
  227. static char    *Extensions [] = { "", ".exe"};
  228. static char    path_line[FFNAME_MAX];    /* Execution path        */
  229. static char    FailName[NAME_MAX + PATH_MAX + 3];
  230.  
  231. #else
  232.  
  233. #define EXTENSION_COUNT        3
  234. static char    *Extensions [] = { "", ".exe", ".com"};
  235.  
  236. #endif
  237.  
  238. /*
  239.  * Word List structure
  240.  */
  241.  
  242. typedef struct wdblock {
  243.     short    w_bsize;
  244.     short    w_nword;
  245.     char    *w_words[1];
  246. } Word_B;
  247.  
  248. /*
  249.  * Extract field from a line
  250.  */
  251.  
  252. typedef struct Fields {
  253.     FILE    *FP;            /* File handler            */
  254.     char    *Line;            /* Line buffer            */
  255.     int        LineLength;        /* Line Length            */
  256.     Word_B    *Fields;    /* ptr to the start of fields    */
  257. } LineFields;
  258.  
  259. /*
  260.  * Program type
  261.  */
  262.  
  263. static struct ExecutableProcessing {
  264.     char        *Name;
  265.     unsigned int    Flags;
  266.     unsigned char    FieldSep;
  267. } ExecProcessingMode;
  268.  
  269. /* Flags set a bit to indicate program mode */
  270.  
  271. #define EP_NONE        0x000        /* Use PSP command line        */
  272. #define EP_DOSMODE    0x001        /* Use DOS mode extended line    */
  273. #define EP_UNIXMODE    0x002        /* Use UNIX mode extended line    */
  274. #define EP_NOEXPAND    0x004        /* Use -f for this command    */
  275. #define EP_ENVIRON    0x008        /* Use environ for variable    */
  276. #define EP_NOSWAP    0x010        /* Do not swap for this command    */
  277. #define EP_COMSPEC    0x020        /* Special for .bat files    */
  278. #define EP_EXPORT    0x040        /* Use -m for this command    */
  279. #define EP_CONVERT    0x080        /* Use conversion        */
  280. #define EP_NOWORDS    0x100        /* Do word expansion        */
  281. #define EP_NOQUOTE    0x200        /* No quote protection        */
  282.  
  283. /*
  284.  * Missing errno values
  285.  */
  286.  
  287. #ifndef EIO
  288. #  define EIO        105    /* I/O error                */
  289. #endif
  290.  
  291. #ifndef E2BIG
  292. #  define E2BIG        107    /* Arg list too long            */
  293. #endif
  294.  
  295. #ifndef ENOTDIR
  296. #  define ENOTDIR    120    /* Not a directory            */
  297. #endif
  298.  
  299. /*
  300.  * Common fields in EXTENDED_LINE file
  301.  */
  302.  
  303. #define COMMON_FIELD_COUNT    5
  304.  
  305. static struct CommonFields {
  306.     char        *Name;
  307.     unsigned int    Flag;
  308. } CommonFields [] = {
  309.     { "switch",        EP_CONVERT },
  310.     {